package com.wangwen.wechatmp.wxpkg.config;

import com.google.common.collect.Maps;
import com.wangwen.wechatmp.dao.ConfWxmpDao;
import com.wangwen.wechatmp.model.ConfWxmp;
import com.wangwen.wechatmp.wxpkg.handler.*;
import com.wangwen.wechatmp.wxpkg.handler.*;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.api.WxConsts.MenuButtonType;
import me.chanjar.weixin.common.api.WxConsts.XmlMsgType;
import me.chanjar.weixin.mp.api.*;
import me.chanjar.weixin.mp.api.impl.WxMpCardServiceImpl;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Configuration
//@ConditionalOnClass(WxMpService.class)
//@EnableConfigurationProperties(WxMpProperties.class)
public class WxMpConfiguration {
	@Autowired(required = false)
	private WxMpProperties properties;
	@Autowired
	private LogHandler logHandler;
	@Autowired
	private LocationHandler locationHandler;
	@Autowired
	private MenuHandler menuHandler;
	@Autowired
	private MsgHandler msgHandler;
	@Autowired
	private UnsubscribeHandler unsubscribeHandler;
	@Autowired
	private SubscribeHandler subscribeHandler;
	@Autowired
	private ScanHandler scanHandler;
	@Autowired
	private ConfWxmpDao confWxmpDao;

	private List<ConfWxmp> confList;
	private static Map<String, WxMpMessageRouter> routers = Maps.newHashMap();
	private static Map<String, WxMpService> mpServices = Maps.newHashMap();


//	@Bean
//	@ConditionalOnMissingBean
//	public WxMpConfigStorage configStorage() {
//		WxMpInMemoryConfigStorage configStorage = new WxMpInMemoryConfigStorage();
//		configStorage.setAppId(this.properties.getAppId());
//		configStorage.setSecret(this.properties.getSecret());
//		configStorage.setToken(this.properties.getToken());
//		configStorage.setAesKey(this.properties.getAesKey());
//		return configStorage;
//	}

	public static WxMpService getMpService(String appId) {
		return mpServices.get(appId);
	}
	public static Map<String, WxMpMessageRouter> getRouters() {
		return routers;
	}

	@Autowired
	public WxMpConfiguration(LogHandler logHandler,  LocationHandler locationHandler,
							 MenuHandler menuHandler, MsgHandler msgHandler, UnsubscribeHandler unsubscribeHandler,
							 SubscribeHandler subscribeHandler, List<ConfWxmp> confList) {
		this.logHandler = logHandler;
		this.locationHandler = locationHandler;
		this.menuHandler = menuHandler;
		this.msgHandler = msgHandler;
		this.unsubscribeHandler = unsubscribeHandler;
		this.subscribeHandler = subscribeHandler;
		this.confList = confList;
	}

	@PostConstruct
	public void initServices() {
		this.confList = (List<ConfWxmp>) confWxmpDao.findAll();
		mpServices = this.confList.stream().map(a -> {
					WxMpInMemoryConfigStorage configStorage = new WxMpInMemoryConfigStorage();
					configStorage.setAppId(a.getAppId());
					configStorage.setSecret(a.getSecret());
					configStorage.setToken(a.getToken());
					configStorage.setAesKey(a.getAesKey());
					WxMpService service = new WxMpServiceImpl();
					service.setWxMpConfigStorage(configStorage);
					routers.put(a.getAppId(), this.router(service));
					return service;
				}
		).collect(Collectors.toMap(service -> service.getWxMpConfigStorage().getAppId(), a -> a));
	}
//	@Bean
//	@ConditionalOnMissingBean
//	public WxMpService WxMpService(WxMpConfigStorage configStorage) {
//		// WxMpService WxMpService = new
//		// me.chanjar.weixin.cp.api.impl.okhttp.WxMpServiceImpl();
//		// WxMpService WxMpService = new
//		// me.chanjar.weixin.cp.api.impl.jodd.WxMpServiceImpl();
//		// WxMpService WxMpService = new
//		// me.chanjar.weixin.cp.api.impl.apache.WxMpServiceImpl();
//		WxMpService service = new WxMpServiceImpl();
//		service.setWxMpConfigStorage(configStorage);
//		return service;
//	}


//	//微信会员卡

	public static WxMpCardService WxMpCardService(WxMpService wxMpService) {
		WxMpCardService wxMpCardService = new WxMpCardServiceImpl(wxMpService);
		return wxMpCardService;
	}

	public WxMpMessageRouter router(WxMpService wxMpService) {
		final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService);

		// 记录所有事件的日志 （异步执行）
		newRouter.rule().handler(this.logHandler).next();

		// 自定义菜单事件
		newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(MenuButtonType.CLICK)
				.handler(this.getMenuHandler()).end();

		// 点击菜单连接事件
		/*newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(MenuButtonType.VIEW)
				.handler(this.nullHandler).end();*/

		// 关注事件
		newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(WxConsts.EventType.SUBSCRIBE)
				.handler(this.getSubscribeHandler()).end();

		// 取消关注事件
		newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(WxConsts.EventType.UNSUBSCRIBE)
				.handler(this.getUnsubscribeHandler()).end();

		// 上报地理位置事件
		newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(WxConsts.EventType.LOCATION)
				.handler(this.getLocationHandler()).end();

		// 接收地理位置消息
		newRouter.rule().async(false).msgType(XmlMsgType.LOCATION).handler(this.getLocationHandler()).end();

		// 扫码事件
		newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(WxConsts.EventType.SCAN)
				.handler(this.getScanHandler()).end();

		// 默认
		newRouter.rule().async(false).handler(this.getMsgHandler()).end();

		return newRouter;
	}

	protected MenuHandler getMenuHandler() {
		return this.menuHandler;
	}

	protected SubscribeHandler getSubscribeHandler() {
		return this.subscribeHandler;
	}

	protected UnsubscribeHandler getUnsubscribeHandler() {
		return this.unsubscribeHandler;
	}

	protected AbstractHandler getLocationHandler() {
		return this.locationHandler;
	}

	protected MsgHandler getMsgHandler() {
		return this.msgHandler;
	}

	protected ScanHandler getScanHandler() {
		return this.scanHandler;
	}

}